<?php
if (!class_exists('AlfaCacheManager')) {

	require_once("Singleton_Interface.php");
	require_once("lib/Zend/Cache.php");

	/**
	 * @author Alecsandru Gabriel DINU
	 * @since Jun 12, 2008
	 *
	 * Cache wrapper manager for Zend Cache.
	 */
	class AlfaCacheManager implements Singleton_Interface {

		private static $theInstance;
		private static $cache;
		const cache_backend = 'File';
		const cache_frontend = 'Core';
		private static $regions;
		private static $active;
	  
		/**
		 * Singleton class constructor
		 * @access private
		 */
		private function __construct() {
			$this->load();
		}

		/**
		 * Singleton factory method
		 * @access public
		 * @return AlfaCacheManager
		 */
		public static function getInstance() {
			if (!self::$theInstance) {
				self::$theInstance = new AlfaCacheManager();
			}
			return self::$theInstance;
		}

		/**
		 * Initializes the cache
		 * @access public
		 */
		private function load() {
			$this->active = true;

			$backend_options = array();
			$frontend_options = array('lifetime' => null, 'automatic_serialization' => true);
			$cache = Zend_Cache::factory(self::cache_frontend, self::cache_backend,
			$frontend_options, $backend_options);
			$this->regions['eternal'] = $cache;

			$backend_options = array();
			$frontend_options = array('automatic_serialization' => true);
			$cache = Zend_Cache::factory(self::cache_frontend, self::cache_backend,
			$frontend_options, $backend_options);
			$this->regions['default'] = $cache;
		}

		/**
		 * Checks if an eternal elements is in cache
		 * @access public
		 * @param mixed
		 * @return boolean
		 */
		public function isEternalElement($key) {
			if (!$this->active) {return false;}
			$cache = $this->regions['eternal'];
			return $cache->test($key);
		}
	  
		/**
		 * Checks if a default cache element exists
		 * @access public
		 * @param mixed
		 * @return boolean
		 */
		public function isElement($key) {
			if (!$this->active) {return false;}
			$cache = $this->regions['default'];
			return $cache->test($key);
		}
	  
		/**
		 * Gets an eternal element from cache
		 * @access public
		 * @param mixed
		 * @return mixed
		 */
		public function getEternalElement($key) {
			if (!$this->active) {return false;}
			$cache = $this->regions['eternal'];
			return $cache->load($key);
		}
	  
		/**
		 * Gets a default element from cache
		 * @access public
		 * @param mixed
		 * @return mixed
		 */
		public function getElement($key) {
			if (!$this->active) {return false;}
			$cache = $this->regions['default'];
			return $cache->load($key);
		}
	  
		/**
		 * Puts an eternal element in cache
		 * @access public
		 * @param mixed
		 * @param mixed
		 * @return boolean
		 */
		public function putEternalElement($key, $value) {
			if (!$this->active) {return false;}
			$cache = $this->regions['eternal'];
			return $cache->save($value, $key);
		}

		/**
		 * Puts a default element in cache
		 * @access public
		 * @param mixed
		 * @param mixed
		 * @return boolean
		 */
		public function putElement($key, $value) {
			if (!$this->active) {return false;}
			$cache = $this->regions['default'];
			return $cache->save($value, $key);
		}
	  
		/**
		 * Forces the config file to be read again
		 * @access public
		 */
		public function reload() {
			// Clean all caches
			$cache = $this->regions['eternal'];
			$cache->clean(Zend_Cache::CLEANING_MODE_ALL);
				
			$cache = $this->regions['default'];
			$cache->clean(Zend_Cache::CLEANING_MODE_ALL);
				
			$this->load();
		}

		/**
		 * Sets the status of the cache manager
		 * @access public
		 * @param boolean
		 */
		public function setActive($active) {
			$this->active = $active;
		}

		/**
		 * Returns the status of the cache manager
		 * @access public
		 * @return boolean
		 */
		public function getActive() {
			return 	$this->active;
		}

		/**
		 * Override clone method to throw exception
		 * @access public
		 * @return void
		 * @throws Exception
		 */
		public function __clone() {
			throw new Exception('You cannot clone singleton object');
		}

	  
	}
}